package com.skyline.attraction.controller;

import java.util.List;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.view.RedirectView;

import com.skyline.attraction.model.Attraction;
import com.skyline.attraction.model.AttractionRefrence;
import com.skyline.attraction.service.AttractionRefrenceService;
import com.skyline.attraction.service.AttractionService;
import com.skyline.attraction.type.AttractionRefrenceType;
import com.skyline.base.controller.BaseController;
import com.skyline.base.exception.NoOperatePermissionException;
import com.skyline.base.exception.NoResourceException;
import com.skyline.base.exception.NotLoginException;
import com.skyline.base.type.Authority;
import com.skyline.common.bean.Page;
import com.skyline.common.util.CommonUtils;
import com.skyline.common.util.Constant;
import com.skyline.common.util.ViewPaths;
import com.skyline.common.util.WebHelper;
import com.skyline.user.model.User;
import com.skyline.wo.model.Album;
import com.skyline.wo.model.Article;
import com.skyline.wo.model.Photo;
import com.skyline.wo.service.ArticleService;

@RequestMapping("/attraction/ref")
@Controller
public class AttractionRefrenceController extends BaseController {
	private static final Log LOGGER = LogFactory.getLog(AttractionRefrenceController.class);
	@Autowired
	private AttractionService attractionService;
	@Autowired
	private AttractionRefrenceService attractionRefrenceService;
	@Autowired
	private ArticleService articleService;

	private @Value("${attraction.listrefrence.pagesize}")
	int listRefrencePageSize;

	private @Value("${attraction.addalbumrefrence.pagesize}")
	int addAlbumRefrencePageSize;

	private @Value("${attraction.addarticlerefrence.pagesize}")
	int addArticleRefrencePageSize;

	/**
	 * 直接递交照片ref
	 * 
	 * @param attractionId
	 * @param refrenceId
	 * @return
	 */
	@RequestMapping(value = "/{attractionId}/photo/upload", method = RequestMethod.GET)
	public ModelAndView batchUpload(@PathVariable("attractionId") Long attractionId,
			@RequestParam(value = "refrenceId", required = false) Long refrenceId) {
		User user = checkAndReturnLoginedUser();
		Long userId = user.getId();

		AttractionRefrence refrence = null;
		Album album = null;
		// FIXME 挑选上传相册方案（比如通过名字选择等）
		if (refrenceId != null) {
			refrence = attractionRefrenceService.getRefrenceForChange(refrenceId, AttractionRefrenceType.ALBUM, userId);
			album = albumService.getAlbumForChange(refrence.getRefId(), userId);
		} else {
			Attraction attraction = attractionService.getAttractionForChange(attractionId, userId);

			String attractionName = attraction.getName();
			String introduction = attraction.getIntroduction();

			album = new Album();
			album.setAlbumName(attractionName);
			album.setPlace(attraction.getCity());
			album.setDescription(introduction);
			album.setAuthority(Authority.PUBLIC);

			album = albumService.createAlbum(user, album);

			Long refId = album.getId();
			String cover = album.getCover() + '.' + album.getCoverExt();

			refrenceId = attractionRefrenceService.addRefrence(refId, cover, attractionName, introduction,
					AttractionRefrenceType.ALBUM, attraction, user);
		}

		ModelAndView view = new ModelAndView(ViewPaths.ATTRACTION_REF_UPLOAD);
		view.addObject("album", album);
		view.addObject("attractionId", attractionId);
		view.addObject("refrenceId", refrenceId);
		return view;
	}

	/**
	 * 
	 * @param ownerId
	 * @param albumId
	 * @param files
	 * @return
	 */
	@RequestMapping(value = "/buploadok/{albumId}", method = RequestMethod.POST)
	public @ResponseBody
	Map<String, Object> batchUploadOk(@PathVariable("albumId") Long albumId, @RequestParam("files") String files) {
		try {
			User user = checkAndReturnLoginedUser();
			return batchUploadOk(albumId, files, user);
		} catch (NotLoginException e) {
			return toJsonMap(false, "压缩图片必须登录", false);
		} catch (NoResourceException e) {
			LOGGER.warn("压缩图片失败，资源不存在", e);
			return toJsonMap(false, "没有找到对应景点或者相册，压缩图片失败！", true);
		} catch (NoOperatePermissionException e) {
			LOGGER.warn("压缩图片失败，无操作权限", e);
			return toJsonMap(false, "没有找到对应相册，压缩图片失败！", true);
		} catch (Exception e) {
			LOGGER.warn("压缩图片失败", e);
			return toJsonMap(false, "压缩图片失败！", true);
		}
	}

	@RequestMapping(value = "/uploadok/{refrenceId}", method = RequestMethod.GET)
	public ModelAndView uploadOk(@PathVariable("refrenceId") Long refrenceId) {
		User user = checkAndReturnLoginedUser();
		Long userId = user.getId();

		AttractionRefrence refrence = attractionRefrenceService.getRefrenceForChange(refrenceId,
				AttractionRefrenceType.ALBUM, userId);
		
		Album album = albumService.getAlbumForChange(refrence.getRefId(), userId);
		
		ModelAndView mav = new ModelAndView(ViewPaths.ATTRACTION_REF_UPLOADOK);
		mav.addObject("refrence", refrence);
		mav.addObject("album", album);
		return mav;
	}

	/**
	 * 打开上传图片到相册的页面
	 * 
	 * @param albumId
	 *            相册ID
	 * @param request
	 * */
	@RequestMapping(value = "/{refrenceId}/upload", method = RequestMethod.GET)
	public ModelAndView toUpload(@PathVariable("refrenceId") Long refrenceId) {
		User user = checkAndReturnLoginedUser();
		Long userId = user.getId();

		AttractionRefrence refrence = attractionRefrenceService.getRefrenceForChange(refrenceId,
				AttractionRefrenceType.ALBUM, userId);
		Album album = albumService.getAlbumForChange(refrence.getRefId(), userId);

		ModelAndView view = new ModelAndView(ViewPaths.ATTRACTION_REF_TOUPLOAD);
		view.addObject("refrenceId", refrenceId);
		view.addObject("attractionId", refrence.getAttractionId());
		view.addObject("album", album);
		return view;
	}

	/**
	 * 打开上传图片到相册的页面
	 * 
	 * @param albumId
	 *            相册ID
	 * @param request
	 * */
	@RequestMapping(value = "/{refrenceId}/upload", method = RequestMethod.POST)
	public ModelAndView normalUpload(@PathVariable("refrenceId") Long refrenceId, String submitToken,
			MultipartHttpServletRequest request) {
		User user = checkAndReturnLoginedUser();
		Long userId = user.getId();

		String errMsg = validateForm("normalUploadForm", submitToken);
		if (errMsg != null) {
			ModelAndView returnMav = toUpload(refrenceId);
			return processValidationErrors("errMsg", errMsg, returnMav);
		}

		AttractionRefrence refrence = attractionRefrenceService.getRefrenceForChange(refrenceId,
				AttractionRefrenceType.ALBUM, userId);
		Album album = albumService.getAlbumForChange(refrence.getRefId(), userId);

		ModelAndView view = normalUpload(album.getId(), user, request, ViewPaths.ATTRACTION_REF_TOUPLOAD,
				ViewPaths.ATTRACTION_REF_UPLOADOK);

		view.addObject("refrence", refrence);
		view.addObject("refrenceId", refrenceId);
		view.addObject("attractionId", refrence.getAttractionId());
		return view;
	}

	@RequestMapping(value = "/uploadok/{refrenceId}", method = RequestMethod.POST)
	public ModelAndView uploadOK(@PathVariable("refrenceId") Long refrenceId, String cover, String ext,
			@RequestParam("description") List<String> descriptions, @RequestParam("id") List<Long> ids,
			String submitToken) {
		User user = checkAndReturnLoginedUser();
		Long userId = user.getId();

		ModelAndView returnMav = null;
		String errMsg = validateForm("uploadOkForm", submitToken);
		if (errMsg != null) {
			returnMav = uploadOk(refrenceId);
			return processValidationErrors("errMsg", errMsg, returnMav);
		}

		int size = Math.min(ids.size(), descriptions.size());
		StringBuilder errMsgBuilder = new StringBuilder();
		for (int i = 0; i < size; i++) {
			if (ids.get(i) == null) {
				LOGGER.warn("操作失败，ID为:" + refrenceId + "的景点引用相册提交的第" + i + "张图片的ID为空");
			}
			errMsg = validateForm("descriptionOnlyForm", descriptions.get(i));
			if (errMsg != null) {
				if (returnMav == null) {
					returnMav = uploadOk(refrenceId);
				}
				errMsgBuilder.append("第").append(i + 1).append("张图片的").append(errMsg);
				return processValidationErrors("errMsg", errMsgBuilder.toString(), returnMav);
			}
		}

		AttractionRefrence refrence = attractionRefrenceService.getRefrenceForChange(refrenceId,
				AttractionRefrenceType.ALBUM, userId);
		Long albumId = refrence.getRefId();
		Long attractionId = refrence.getAttractionId();

		albumService.changePhotosDescription(albumId, ids, descriptions);
		albumService.changeAlbumCover(userId, albumId, cover, ext);

		if (StringUtils.hasLength(cover) && StringUtils.hasLength(ext)) {
			attractionRefrenceService.updateRefPortrait(refrenceId, cover + "." + ext);
		}

		WebHelper.removeSessionAttribute(null, Constant.SESSION_UPLOAD_OK_FILES);

		String url = buildRecirectPath("/attraction/view/" + attractionId);
		ModelAndView view = new ModelAndView(new RedirectView(url));
		return view;
	}

	/**
	 * 用于为景点添加ref，refType分为album，article等，可以从自己的相册或
	 * 日志列表选择已有的添加到ref，也可以直接新建，新建之后也将根据type类型分别 在用户的相册或日志下添加该相册，照片，或日志
	 * 
	 * @param attractionId
	 * @param page
	 * @return
	 */
	@RequestMapping(value = "/add/{attractionId}", method = RequestMethod.GET)
	public ModelAndView addRefrence(@PathVariable("attractionId") Long attractionId,
			@RequestParam("type") AttractionRefrenceType type, Page page) {

		User user = checkAndReturnLoginedUser();
		Long userId = user.getId();

		Attraction attraction = attractionService.getAttractionForChange(attractionId, userId);

		ModelAndView view = new ModelAndView(ViewPaths.ATTRACTION_REF_ADD);
		view.addObject("attraction", attraction);

		switch (type) {
		case ALBUM:
			page.setSize(addAlbumRefrencePageSize);
			List<Album> albums = attractionRefrenceService.queryAlbumsWithRefed(userId, attractionId, page);
			view.addObject("albums", albums);
			break;
		case TRAVELNOTE:
			page.setSize(addArticleRefrencePageSize);
			List<Article> articles = attractionRefrenceService.queryArticlesWithRefed(userId, attractionId, page);
			view.addObject("articles", articles);
			break;
		default:
			throw new NoResourceException("不存在投寄资源");
		}

		view.addObject("page", page);
		view.addObject("type", type);
		return view;
	}

	@RequestMapping(value = "/add/{attractionId}", method = RequestMethod.POST)
	public @ResponseBody
	Map<String, Object> addRefrence(@PathVariable("attractionId") Long attractionId, @RequestParam("refId") Long refId,
			@RequestParam("type") AttractionRefrenceType type) {
		try {
			User user = checkAndReturnLoginedUser();
			Long userId = user.getId();

			Attraction attraction = attractionService.getAttractionForChange(attractionId, userId);

			if (attractionRefrenceService.isRefrenceExist(attractionId, type, refId)) {
				return toJsonMap(false, "已经投寄过该资源", true);
			}

			String refPortrait = null;
			String refTitle = null;
			String refDigest = null;
			switch (type) {
			case ALBUM:
				Album album = albumService.getAlbumForChange(refId, userId);
				refPortrait = album.getCover() + '.' + album.getCoverExt();
				refTitle = CommonUtils.nullStringToEmpty(album.getAlbumName());
				refDigest = CommonUtils.nullStringToEmpty(album.getDescription());
				break;
			case TRAVELNOTE:
				Article article = articleService.getArticleById(refId);
				refTitle = CommonUtils.nullStringToEmpty(article.getTitle());
				refDigest = CommonUtils.nullStringToEmpty(article.getDigest());
				break;
			default:
				throw new NoResourceException("不存在投寄资源");
			}

			attractionRefrenceService.addRefrence(refId, refPortrait, refTitle, refDigest, type, attraction, user);
			return toJsonMap(true, "投寄成功", true);
		} catch (NotLoginException e) {
			return toJsonMap(false, "您登陆已超时，请重新登陆", false);
		} catch (NoResourceException e) {
			LOGGER.warn("投寄目标不存在", e);
			return toJsonMap(false, "没有找到对应资源，可能该资源已被删除！", true);
		} catch (NoOperatePermissionException e) {
			LOGGER.warn("无投寄权限", e);
			return toJsonMap(false, "对不起，您没有投寄的权限！", true);
		} catch (Exception e) {
			LOGGER.warn("投寄失败", e);
			return toJsonMap(false, "对不起，投寄失败！", true);
		}
	}

	/**
	 * 查看ref
	 * 
	 * @param attractionId
	 * @param type
	 * @param page
	 * @return
	 */
	@RequestMapping(value = "/list/{attractionId}", method = RequestMethod.GET)
	public ModelAndView listRefrence(@PathVariable("attractionId") Long attractionId,
			@RequestParam(value = "type", required = false) AttractionRefrenceType type, Page page) {

		page.setSize(listRefrencePageSize);

		Attraction attraction = attractionService.getNormalAttraction(attractionId);
		List<AttractionRefrence> refrenceList = attractionRefrenceService.listRefrencesOfAttraction(
				attractionId, type, page);

		ModelAndView view = new ModelAndView(ViewPaths.ATTRACTION_REF_LIST);
		view.addObject("attraction", attraction);
		view.addObject("refrenceList", refrenceList);
		view.addObject("type", type);
		view.addObject("page", page);
		return view;
	}

	@RequestMapping(value = "/{id}", method = RequestMethod.GET)
	public ModelAndView viewRefrence(@PathVariable("id") Long id) {
		AttractionRefrence refrence = attractionRefrenceService.getRefrenceById(id);
		AttractionRefrenceType type = refrence.getRefType();
		Long refId = refrence.getRefId();

		ModelAndView view = new ModelAndView();
		switch (type) {
		case ALBUM:
			List<Photo> photos = albumService.listPhotoFilesOfAlbum(refId, Authority.PUBLIC);
			view.setViewName(ViewPaths.ATTRACTION_REF_PHOTO);
			view.addObject("photos", photos);
			break;
		case TRAVELNOTE:
			Article article = articleService.getArticleById(refId);
			view.setViewName(ViewPaths.ATTRACTION_REF_ARTICLE);
			view.addObject("ARTICLE", article);
			break;
		default:
			throw new NoResourceException("不存在投寄资源");
		}

		view.addObject("refrence", refrence);
		return view;
	}

}
